package com.liuyi.netty.im.test.im.client;

import com.liuyi.netty.im.commons.codes.CodeConst;
import com.liuyi.netty.im.commons.codes.LimProtocol;
import com.liuyi.netty.im.commons.codes.data.DataEvent;
import com.liuyi.netty.im.test.im.listeners.ImCode;
import com.liuyi.netty.im.test.im.listeners.ImListener;
import com.liuyi.netty.im.test.im.listeners.ImListenerManage;
import com.liuyi.netty.im.test.util.Pair;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;

/**
 * @author Mr.Fmy
 * @since 2022/1/19
 */
@Slf4j
public class ClientSdkHandler extends SimpleChannelInboundHandler<LimProtocol> {


    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        listener(ctx.channel(), ImCode.OPEN, null);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        listener(ctx.channel(), ImCode.CLOSE, null);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, LimProtocol msg) throws Exception {
        CodeConst.Command command = msg.getCommand();
        if (!command.equals(CodeConst.Command.EVENT)) {
            //不是事件通知就不用处理了
            return;
        }
        if (msg.getData() != null) {
            DataEvent data = (DataEvent) msg.getData();
            ImCode code = ImCode.valueOf(data.getEvent().name());
            listener(ctx.channel(), code, data.getData());
        }
    }

    private void listener(Channel channel, ImCode code, Object data) {
        Pair<ImListener, ExecutorService> pair = ImListenerManage.get(code);
        if (pair == null) {
            return;
        }
        Runnable runnable = () -> {
            try {
                pair.getObject1().handler(channel, data);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        };
        try {
            pair.getObject2().execute(runnable);
        } catch (RejectedExecutionException ex) {
            log.warn("Reject ImServer request,cause={}", ex.getMessage());
        }
    }
}
